/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.bef.core.action.modify;

import com.inspur.edp.bef.api.action.VoidActionResult;
import com.inspur.edp.bef.api.action.assembler.IMgrActionAssembler;
import com.inspur.edp.bef.api.be.IBEManagerContext;
import com.inspur.edp.bef.api.be.IBusinessEntity;
import com.inspur.edp.bef.api.parameter.retrieve.RetrieveParam;
import com.inspur.edp.bef.api.parameter.retrieve.RetrieveResult;
import com.inspur.edp.bef.core.action.AuthorityUtil;
import com.inspur.edp.bef.core.lock.LockUtils;
import com.inspur.edp.bef.core.session.FuncSessionManager;
import com.inspur.edp.bef.entity.exception.BefExceptionBase;
import com.inspur.edp.bef.entity.exception.ExceptionLevel;
import com.inspur.edp.bef.spi.action.AbstractManagerAction;
import com.inspur.edp.cef.entity.changeset.ModifyChangeDetail;
import com.inspur.edp.cef.entity.condition.EntityFilter;
import com.inspur.edp.cef.entity.entity.IEntityData;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

public class ModifyByFilterMgrAction extends AbstractManagerAction<VoidActionResult>
{

		//region Constructor

	public ModifyByFilterMgrAction(IBEManagerContext managerContext, EntityFilter filter, ModifyChangeDetail changeDetail)
	{
		super(managerContext);
		this.filter = filter;
		this.changeDetail = changeDetail;
	}


		//endregion


		//region 属性字段
	private EntityFilter filter;

	private ModifyChangeDetail changeDetail;


		//endregion


		//region  Override
	@Override
	public final void execute() {
		getBEManagerContext().checkAuthority("Modify");
//		AuthorityUtil.checkAuthority("Modify");
//		FuncSessionManager.getCurrentSession().getBefContext().setCurrentOperationType("Modify");
List<IEntityData> queryRez = getBEManagerContext().getBEManager().query(filter);
		if (queryRez == null || queryRez.size() == 0)
		{
			return;
		}

List<String> ids = queryRez.stream().map(item -> item.getID()).collect(Collectors.toList());
		RetrieveParam tempVar = new RetrieveParam();
		tempVar.setNeedLock(true);
		RetrieveParam para = tempVar;
RetrieveResult retrieveRez = getBEManagerContext().getBEManager().retrieve(ids, para);
		checkRetrieveResult(ids, retrieveRez);

List<IBusinessEntity> beList = getBEManagerContext().getEntities(ids);
for (IBusinessEntity be : beList)
		{
			ModifyChangeDetail change = new ModifyChangeDetail(be.getID());
for (Map.Entry<String, Object> item : changeDetail.getPropertyChanges().entrySet())
			{
				change.getPropertyChanges().put(item.getKey(), item.getValue());
			}

			be.modify(change);
		}
	}

	/** 
	 检验Retrieve结果，若未全部获取成功，则抛异常，并返回失败ids
	 
	 @param ids 批量Modify的数据id
	 @param result 获取结果
	*/
	private void checkRetrieveResult(List<String> ids, RetrieveResult result)
	{
		Set<String> resultIds = result.getDatas().keySet();
		if (resultIds.size() != ids.size())
		{
			java.util.ArrayList<String> retrieveFailIDs = new java.util.ArrayList<String>();
for (String id : ids)
			{
				if (!resultIds.contains(id))
				{
					retrieveFailIDs.add(id);
				}
			}
			throw new BefExceptionBase("Bef", String.format("批量修改时，以下数据获取失败：%1$s", retrieveFailIDs), null, ExceptionLevel.Error, true);
		}
		if (result.getLockFailedIds() != null && !result.getLockFailedIds().isEmpty())
		{
			LockUtils.throwLockFailed(result.getLockFailedIds().stream().collect(Collectors.toList()), "");
			//throw new BefException(ErrorCodes.EditingLocked, "数据已被其他用户锁定无法修改");//TODO: 使用统一的消息机制
		}
	}

	@Override
	protected final IMgrActionAssembler getMgrAssembler()
	{
		return getMgrActionAssemblerFactory().getModifyByFilterMgrActionAssembler(getBEManagerContext(), filter, changeDetail);
	}

		//endregion
}
